package org.bwf.study.servcie.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.bwf.obj.bo.UserLoginBO;
import org.bwf.obj.bo.UserRegisterBO;
import org.bwf.study.mapper.UserInfoMapper;
import org.bwf.study.model.UserInfo;
import org.bwf.study.servcie.UserService;
import org.bwf.study.util.JwtUtils;
import org.bwf.study.util.MD5;
import org.bwf.study.util.RedisUntil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private RedisUntil redisUntil;

    @Autowired
    private UserInfoMapper userInfoMapper;

    @Override
    public Integer Register(UserRegisterBO userRegisterBO) {

        // 验证 userRegisterBO 里面数据的合法性
        // 验证 验证码是否存在于redis，是否和用户提交的验证码相等
        String key = String.format("reg-%s", userRegisterBO.getUserPhone());
        Object valCode = redisUntil.get(key);
        if(valCode == null){
            log.error("验证码不能为空........");
            return null;
        }
        // 使用Redis中查询到的valCode和用户提交BO中的valCode做对比，如果不相同，就是非法
        if(! valCode.toString().equals(userRegisterBO.getValCode())){
            log.error("验证码非法......");
            return null;
        }

        // 注册处理
        // 再数据库中查询是否有登录名
        // 使用泛型承载 映射类 UserInfo                              使用Wrappers工厂创建 泛型承载对象
        LambdaQueryWrapper<UserInfo> userInfoLambdaQuery = Wrappers.lambdaQuery();
        // 使用LambdaQueryWrapper 进行Sql语句拼接
        // select * from user_info where user_login_name = ''
        userInfoLambdaQuery.eq(UserInfo::getUserLoginName, userRegisterBO.getUserLoginName());
        // 使用操作类 userInfoMapper 执行Sql，得到 实体类集合
        List<UserInfo> userInfoList = userInfoMapper.selectList(userInfoLambdaQuery);
        if(userInfoList.size() > 0){
            log.warn("用户名已经存在........");
            return null;
        }

        String pass = new MD5().md5(userRegisterBO.getUserLoginPass() + userRegisterBO.getNickName());
        UserInfo userInfo = new UserInfo();
        userInfo.setUserLoginName(userRegisterBO.getUserLoginName());
        userInfo.setUserLoginPass(pass);
        userInfo.setUserPhone(userRegisterBO.getUserPhone());
        userInfo.setUserNickName(userRegisterBO.getNickName());
        userInfo.setUserEmail(userRegisterBO.getUserEmail());
        userInfo.setUserEnable((byte)1);

        // result 就是执行数据库以后所影响的行数
        int result = userInfoMapper.insert(userInfo);

        // 这种情况只会在大并发量的情况下发生
        if(result <= 0){
            log.error("数据注册失败......");
            return null;
        }

        return 0;
    }

    @Override
    public String Login(UserLoginBO userLoginBO) {


        LambdaQueryWrapper<UserInfo> userInfoLambdaQuery = Wrappers.lambdaQuery();
        userInfoLambdaQuery.eq(UserInfo::getUserLoginName, userLoginBO.getUserLoginName());
        List<UserInfo> userInfoList = userInfoMapper.selectList(userInfoLambdaQuery);
        if(userInfoList.size() <=0){
            log.info("用户名不存在......");
            return null;
        }
        UserInfo userInfo = userInfoList.get(0);
        String pass = new MD5().md5(userLoginBO.getUserLoginPass() + userInfo.getUserNickName());
        // 使用 userInfo 中的密码和 MD5加盐后的pass进行对比
        if(!userInfo.getUserLoginPass().equals(pass)){
            log.info("密码错误.......");
            return null;
        }

        // 需要生成token
        HashMap<String,Object> tokenMap = new HashMap<>();
        tokenMap.put("userId", userInfo.getUserId());
        String token = JwtUtils.sign(tokenMap, 3600_000);
        // 使用token作为键， userInfo作为值，存放到Redis， 时效  3600 秒
        redisUntil.set(token, userInfo);

        return token;
    }
}
